/*
 * @Author: TC
 * @Date: 2025-01-28 12:35:49
 * @Last Modified by: TC
 * @Last Modified time: 2025-02-13 17:36:17
 */

import fs from "fs";
import path from "path";
import { exec } from "child_process";
let basisuDPath = "";
let root = "";

const extName = [".png", ".jpg", ".jpeg"];
const uncompressedDir = [
    path.join("assets", "unCompressed"),
    path.join("assets", "main"),
    path.join("assets", "internal"),
    path.join("assets", "start-scene"),
];
const cacheList: string[] = [];
let cacheDir = "";

/**
 * 执行basis命令
 * @param command
 */
function runBasis(command: string, cb: Function) {
    exec(command, (error, stdout, stderr) => {
        if (error) {
            console.error(`执行错误: ${error}`);
            return;
        }
        if (stderr) {
            console.error(`标准错误输出: ${stderr}`);
        }
        cb && cb();
    });
}

export function basis() {
    basisuDPath = path.join(__dirname, "..", "tool", "basis", "basisuD.exe");
    root = Editor.Project.path; // 项目根目录
    makeCacheDir();
    let buildPath = path.join(root, "build", "web-mobile"); // 打包构建目录
    // 遍历所有的资源文件
    let compressFiles: string[] = [];
    ["assets", "remote"].forEach((dirName) => {
        if (dirName != "resources") {
            handleDir(path.join(buildPath, dirName), compressFiles);
        }
    });
    let taskList = [];
    for (let filePath of compressFiles) {
        let sp = filePath.split("\\");
        let cachePath = path.join(cacheDir, sp[sp.length - 1]);
        let cache = fs.existsSync(cachePath);
        // cache = null;
        if (cache) {
            fs.copyFileSync(cachePath, filePath);
        } else {
            taskList.push(
                doCompress(filePath).then((data) => {
                    let fileData = fs.readFileSync(data.filePath);
                    fs.writeFileSync(filePath, new Uint8Array(fileData));
                    fs.copyFileSync(filePath, cachePath);
                })
            );
        }
        cacheList.push(cachePath);
    }
    deleteDisusedCache();
    return Promise.all(taskList);
}

/**
 * 创建缓存目录
 */
function makeCacheDir() {
    cacheDir = path.join(root, "cache", "compressedTexture");
    if (!fs.existsSync(cacheDir)) {
        fs.mkdirSync(cacheDir, {
            recursive: true,
        });
    }
}

function deleteDisusedCache() {
    let cacheFiles: string[] = [];
    handleDir(cacheDir, cacheFiles);
    for (const file of cacheFiles) {
        if (!cacheList.includes(file)) {
            fs.unlinkSync(file);
        }
    }
}
/**
 * 执行压缩处理
 * @param texPath
 * @returns
 */
function doCompress(texPath: string): Promise<any> {
    return new Promise((resolve, reject) => {
        let filePath = texPath;
        let cmd = `${basisuDPath} -basis ${texPath} -output_file ${filePath} -q 255`;
        runBasis(cmd, () => {
            resolve({
                filePath: filePath,
            });
        });
    });
}

/**
 * 处理文件夹
 * @param dir
 * @param compressFiles
 * @returns
 */
function handleDir(dir: string, compressFiles: any[]) {
    if (!fs.existsSync(dir)) {
        return;
    }
    let files = fs.readdirSync(dir);
    for (const file of files) {
        let fullPath = path.join(dir, file);
        if (uncompressedDir.some((url) => fullPath.includes(url))) {
            console.log("忽略构建目录：", fullPath);
            continue;
        }
        let stat = fs.statSync(fullPath);
        if (stat.isFile()) {
            let ext = path.extname(fullPath).toLowerCase();
            if (!extName.includes(ext)) {
                continue;
            }
            compressFiles.push(fullPath);
        } else {
            handleDir(fullPath, compressFiles);
        }
    }
}
